using System;
using System.ComponentModel;
using System.Globalization;

namespace GoogleMaps
{
	/// <summary>
	/// A point on Earth represented by longitued and latitude coordinates.
	/// </summary>
	public class GLatLng
	{
		private Decimal lat;
		private Decimal lng;

		/// <summary>
		/// Initializes a new instance of the GLatLng class.
		/// </summary>
		public GLatLng()
		{
		}

		/// <summary>
		/// Initializes a new instance of the GLatLng class.
		/// </summary>
		/// <param name="lat">The latitude coordinate.</param>
		/// <param name="lng">The longitude coordinate.</param>
		public GLatLng(Decimal lat, Decimal lng)
			: this(lat, lng, false)
		{
		}

		/// <summary>
		/// Initializes a new instance of the GLatLng class.
		/// </summary>
		/// <param name="lat">The latitude coordinate.</param>
		/// <param name="lng">The longitude coordinate.</param>
		/// <param name="unbounded">Indicates that the latitude should be bound to values 
		/// between -90 and +90, and the longitude coordinate should be bound to values 
		/// bettwen -180 and +180.</param>
		public GLatLng(Decimal lat, Decimal lng, bool unbounded)
		{
			Lat = lat;
			Lng = lng;
			IsUnbounded = unbounded;
		}

		/// <summary>
		/// Gets or sets the latitude coordinate.
		/// </summary>
		public Decimal Lat
		{
			get { return lat; }
			set
			{
				if (!IsUnbounded && (value < -90 || value > 90))
					throw new ArgumentOutOfRangeException(Properties.Resources.LatOutOfRange);

				lat = value;
			}
		}

		/// <summary>
		/// Gets or sets the longitude coordinate.
		/// </summary>
		public Decimal Lng
		{
			get { return lng; }
			set
			{
				if (!IsUnbounded && (value < -180 || value > 180))
					throw new ArgumentOutOfRangeException(Properties.Resources.LngOutOfRange);

				lng = value;
			}
		}

		/// <summary>
		/// Gets a flag indicating that the latitude should be bound to values 
		/// between -90 and +90, and the longitude coordinate should be bound to values 
		/// bettwen -180 and +180.
		/// </summary>
		public bool IsUnbounded { get; private set; }

		/// <summary>
		/// Renders this class as a javascript string.
		/// </summary>
		public string Render()
		{
			return String.Format(CultureInfo.InvariantCulture, "new GLatLng({0}, {1})", Lat.ToString(CultureInfo.InvariantCulture), Lng.ToString(CultureInfo.InvariantCulture));
		}
	}
}
